from pydantic import BaseModel
from typing import List, Optional


class ServerException(Exception):
    title: str
    code: int

    def __init__(self, msg):
        self.msg = msg

    def __str__(self):
        return self.msg


class ModelNoExists(ServerException):
    code = 4001
    title = "资源不存在"

    def __init__(self, model_type, identify):
        if isinstance(identify, str):
            self.msg = f"{model_type} {identify} doesn't exists"
        elif isinstance(identify, list):
            self.msg = f"can't find {model_type} models: {', '.join(identify)}"


class ModelExists(ServerException):
    code = 4002
    title = "资源冲突"

    def __init__(self, model_type, identify):
        self.msg = f"{model_type} {identify} exists"


class InvalidParam(ServerException):
    code = 4003
    title = "参数错误"

    def __init__(self, param, msg):
        if isinstance(param, list):
            self.msg = f"{param} are invalid, {msg}"
        else:
            self.msg = f"{param} is invalid, {msg}"


class FieldCheckError(BaseModel):
    num: Optional[int]
    field: str
    error: str
    expect: Optional[str]
    example: Optional[str]


class ModelReferenceError(ServerException):
    code = 4004
    title = "实体之间引用关系的异常"

    def __init__(self, model_type, details: List[FieldCheckError]):
        self.details = details
        self.msg = f"{model_type} get reference errors"


class AlterModelError(ServerException):
    code = 4005
    title = "编辑数据的错误提示"

    def __init__(self, model_type, details: List[FieldCheckError]):
        self.details = details
        self.msg = f"alter {model_type} get errors"


if __name__ == '__main__':
    for sub in ServerException.__subclasses__():
        # print(sub.__name__)
        print(f"{sub.code}: {sub.title}")